#include "simplechatgame.h"
#include "chatcommand.h"
#include "Debug.h"

simplechatgame::simplechatgame()
{
	// Constructor.
	gameid = nullptr;
	gamedata = nullptr;
}

simplechatgame::~simplechatgame()
{
	// Destructor.
	simplechatgameuser *item;
	users.deleteallitems();
	users.clear(true);
	idisposable::dereference((idisposable **)&gameid);
	idisposable::dereference((idisposable **)&gamedata);	
}

bool simplechatgame::add_client(chatclient *client,datastring username)
{
	// Adds a client. Returns true if the client was added.
	simplechatgameuser *newuser = new simplechatgameuser();
	if (newuser == nullptr) {
		return false;
	}
	newuser->client = client;
	newuser->username = new datablock(username);
	if (!users.add_to_end(newuser)) {
		delete newuser;
		return false;
	}
	return true;
}

void simplechatgame::send_message_to_clients(message *message,chatclient *me)
{
	DEBUG_FUNCTION
	biglist_iterator<simplechatgameuser *>clientloop(&users);
	DEBUG_LINE
	chatclient *client;
	DEBUG_LINE
	while(!clientloop.eof()) {
		DEBUG_LINE
		client = clientloop.item->client;
		DEBUG_LINE
		if ((client != me) && (client != nullptr)) {
			DEBUG_LINE
			client->add_message(message);
			client->callback_on_writable();
			DEBUG_LINE
		}
		DEBUG_LINE
		clientloop.movenext();
	}
	DEBUG_LINE
	return;
}

simplechatgame *simplechatgame::clone()
{
	usage++;
	return this;
}

void simplechatgame::send_user_list_to_clients()
{
	DEBUG_FUNCTION
	message *user_list_message;
	DEBUG_LINE
	user_list_message = chatcommand::simplegameusers(0,*gameid,&users);
	DEBUG_LINE
	send_message_to_clients(user_list_message,nullptr);
	DEBUG_LINE
	if (--user_list_message->usage <= 0) {
		DEBUG_LINE
		delete user_list_message;
	}
	//idisposable::dereference((idisposable**)user_list_message);
	DEBUG_LINE
}

int simplechatgame::usercount(bool withclient)
{
	// Returns the number of users. If withclient is true then only count users that are connected.
	DEBUG_FUNCTION
	int count = 0;
	DEBUG_LINE
	biglist_iterator<simplechatgameuser *> loop(&users);
	DEBUG_LINE
	while (!loop.eof()) {
		DEBUG_LINE
		if ((!withclient) || (loop.item->client != nullptr)) {
			count++;
		}
		DEBUG_LINE
		loop.movenext();
		DEBUG_LINE
	}
	DEBUG_LINE
	return count;
}

biglist_item<simplechatgameuser *> *simplechatgame::add_user(chatclient *client,datastring username)
{
	// Adds a user to users. Returns the added item if successful.
	biglist_item<simplechatgameuser *> *item = nullptr;
	simplechatgameuser *user;
	user = new simplechatgameuser();
	if (user != nullptr) {
		user->client = client;
		user->username = new datablock(username);
		if (user->username == nullptr) {
			delete user;
		} else {
			item = users.add(user);
			if (item == nullptr) {
				delete user;
			}
		}
	}	
	return item;
}

biglist_item<simplechatgameuser *> *simplechatgame::getuser(chatclient *client)
{
	// Search user by client.
	biglist_iterator<simplechatgameuser *> loop(&users);
	while (!loop.eof()) {
		if (loop.item->client == client) {
			return loop.row;
		}
		loop.movenext();
	}
	return nullptr;
}
biglist_item<simplechatgameuser *> *simplechatgame::getuser(datastring username)
{
	// Search user by username.
	biglist_iterator<simplechatgameuser *> loop(&users);
	while (!loop.eof()) {
		if (username == *(loop.item->username)) {
			return loop.row;
		}
		loop.movenext();
	}
	return nullptr;
}